package com.symaster.common.swing.element;

import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.symaster.common.entity.Page;
import com.symaster.common.swing.config.AppConfig;
import com.symaster.common.swing.style.Style;
import com.symaster.common.swing.util.SwingUtil;
import org.apache.commons.lang3.StringUtils;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.*;

/**
 * @author yinmiao
 * @date 2021-12-06 15:25
 */
public class SyzdPagination extends JComponent {

    private static final ImageIcon arrow_left = SwingUtil.loadIconEnabledCache("arrow-left_200X200.png", 12, 12);
    private static final ImageIcon arrow_right = SwingUtil.loadIconEnabledCache("arrow-right_200X200.png", 12, 12);
    private static final Font microsoft_yaHei_ui = new Font("Microsoft YaHei UI", Font.PLAIN, 14);

    private final Integer size = 10;
    private JTextField page_number_input;
    private JButton left_button;
    private JButton right_button;
    private JPanel root_panel;
    private JPanel page_list_area;
    private JPanel panel1;
    private Pagination pagination;
    private Set<PageChangeListener> pageChangeListenerSet;
    private Map<String, JButton> pageListButtonMap;
    private List<JButton> pageListButtonList;
    private Integer pageTotal;

    public SyzdPagination() {
        initPage();
        initListener();
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.setContentPane(new SyzdPagination());
        jFrame.setVisible(true);
    }

    public Pagination getPagination() {
        return pagination;
    }

    public Page getPage() {
        if (pagination == null) {
            return new Page();
        }

        return new Page(pagination.getPage(), pagination.getPageSize());
    }

    public void setPagination(Pagination pagination) {
        this.pagination = pagination;
        if (pagination.total <= 0) {
            pagination.total = 1;
        }
        if (pagination.page < 1) {
            pagination.page = 1;
        }
        if (pagination.pageSize <= 0) {
            pagination.pageSize = 1;
        }
        int i = pagination.total / pagination.pageSize;
        if (pagination.total % pagination.pageSize != 0) {
            i += 1;
        }
        this.pageTotal = i;
        String[] showPageArray = getShowPageArray(pagination, size);

        viewPageArray(showPageArray, pagination.page + "");
        SwingUtilities.invokeLater(() -> setThatPage(pagination.page));
    }

    /**
     * 添加切换页面事件
     */
    public void addPageChangeListener(PageChangeListener listener) {
        if (pageChangeListenerSet == null) {
            pageChangeListenerSet = new HashSet<>();
        }
        pageChangeListenerSet.add(listener);
    }

    private void initListener() {
        page_number_input.registerKeyboardAction(e -> {
            if (pagination == null) {
                return;
            }
            int i = 0;
            try {
                if (!StringUtils.isEmpty(page_number_input.getText())) {
                    i = Integer.parseInt(page_number_input.getText());
                } else {
                    i = 1;
                }
            } catch (NumberFormatException ex) {
                i = 1;
            }
            if (i <= 1) {
                i = 1;
            }
            if (i > pageTotal) {
                i = pageTotal;
            }
            selectPage(i);
        }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        left_button.addActionListener((e) -> {
            if (pagination == null) {
                return;
            }
            if (pagination.page <= 1) {
                return;
            }
            selectPage(pagination.page - 1);
        });
        right_button.addActionListener((e) -> {
            if (pagination == null) {
                return;
            }
            if (pagination.page > pageTotal) {
                return;
            }
            selectPage(pagination.page + 1);
        });
    }

    private void initPage() {
        setLayout(new BorderLayout());
        add(root_panel, BorderLayout.CENTER);

        left_button.setIcon(arrow_left);
        right_button.setIcon(arrow_right);
    }

    private void setThatPage(Integer page) {
        page_number_input.setText(page + "");
    }

    private void viewPageArray(String[] showPageArray, String selectPage) {
        initPageButtonMap();
        initPageButtonList();
        if (pageListButtonList.size() == 0) {
            initViewPageArray(showPageArray, selectPage);
            return;
        }

        pageListButtonMap.clear();
        for (int i = 0; i < showPageArray.length; i++) {
            JButton jButton = pageListButtonList.get(i);
            jButton.setText(showPageArray[i] + "");
            setPageButtonText(selectPage, jButton, showPageArray[i]);
            pageListButtonMap.put(showPageArray[i], jButton);
        }
        page_list_area.setPreferredSize(new Dimension(showPageArray.length * 30, 26));
    }

    private void initViewPageArray(String[] showPageArray, String selectPage) {
        for (String s : showPageArray) {
            JButton jButton = new JButton();
            jButton.setFocusPainted(false);
            jButton.setText(s + "");
            jButton.setBackground(UIManager.getColor("Panel.background"));
            setChangeListener(jButton);
            Style.setBorder(1, jButton);
            setPageButtonText(selectPage, jButton, s);
            page_list_area.add(jButton);
            pageListButtonList.add(jButton);
            pageListButtonMap.put(s, jButton);
        }
        page_list_area.setPreferredSize(new Dimension(showPageArray.length * 30, 26));
    }

    private void setPageButtonText(String selectPageText, JButton jButton, String thatText) {
        if (selectPageText.equals(thatText)) {
            jButton.setFont(microsoft_yaHei_ui);
            jButton.setForeground(AppConfig.getColor("select_color"));
            jButton.setPreferredSize(new Dimension(30, 26));
        } else {
            Style.setFont(1, jButton);
            jButton.setForeground(UIManager.getColor("TextField.foreground"));
            jButton.setPreferredSize(new Dimension(26, 26));
        }
    }

    private void setChangeListener(JButton jButton) {
        jButton.addActionListener((e) -> {
            int i = 0;
            try {
                i = Integer.parseInt(jButton.getText());
                if (i == pagination.page) {
                    return;
                }
            } catch (NumberFormatException ex) {
                return;
            }
            this.selectPage(i);
        });
    }

    private void selectPage(int page) {
        if (page <= 0 || page > pageTotal) {
            return;
        }
        pagination.page = page;
        String[] showPageArray = getShowPageArray(pagination, size);
        this.viewPageArray(showPageArray, pagination.page + "");
        this.setThatPage(pagination.page);
        this.pageChangeListener(pagination);
    }

    private void pageChangeListener(Pagination pagination) {
        if (pageChangeListenerSet == null) {
            return;
        }
        for (PageChangeListener pageChangeListener : pageChangeListenerSet) {
            pageChangeListener.handle(new Page(pagination.page, pagination.pageSize));
        }
    }

    private void initPageButtonMap() {
        if (pageListButtonMap == null) {
            pageListButtonMap = new HashMap<>();
        }
    }

    private void initPageButtonList() {
        if (pageListButtonList == null) {
            pageListButtonList = new ArrayList<>();
        }
    }

    private String[] getShowPageArray(Pagination pagination, int size) {
        List<String> pageNumbers = new ArrayList<>();
        int i1 = size / 2;
        int i2 = 0;
        for (int i = 0; i < ((i2 = size - pageTotal) > 0 ? pageTotal : size); i++) {
            if (pageTotal - pagination.page < i1) {
                pageNumbers.add((pageTotal - size + (Math.max(i2, 0)) + 1 + i) + "");
                continue;
            }
            if (pagination.page > i1) {
                pageNumbers.add((pagination.page - i1 + i) + "");
                continue;
            }

            pageNumbers.add((i + 1) + "");
        }

        return pageNumbers.toArray(new String[0]);
    }

    {
        // GUI initializer generated by IntelliJ IDEA GUI Designer
        // >>> IMPORTANT!! <<<
        // DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        root_panel = new JPanel();
        root_panel.setLayout(new BorderLayout(0, 0));
        root_panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new GridLayoutManager(1, 2, new Insets(0, 15, 0, 0), -1, -1));
        panel2.setPreferredSize(new Dimension(0, 0));
        root_panel.add(panel2, BorderLayout.CENTER);
        panel2.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        panel1 = new JPanel();
        panel1.setLayout(new BorderLayout(0, 0));
        panel2.add(panel1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        panel1.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        left_button = new JButton();
        left_button.setFocusPainted(false);
        left_button.setMaximumSize(new Dimension(25, 25));
        left_button.setMinimumSize(new Dimension(25, 25));
        left_button.setPreferredSize(new Dimension(25, 25));
        left_button.setText("");
        panel1.add(left_button, BorderLayout.WEST);
        right_button = new JButton();
        right_button.setFocusPainted(false);
        right_button.setMaximumSize(new Dimension(25, 25));
        right_button.setMinimumSize(new Dimension(25, 25));
        right_button.setPreferredSize(new Dimension(25, 25));
        right_button.setText("");
        panel1.add(right_button, BorderLayout.EAST);
        page_list_area = new JPanel();
        page_list_area.setLayout(new FlowLayout(FlowLayout.CENTER, 2, 0));
        panel1.add(page_list_area, BorderLayout.CENTER);
        page_list_area.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), null, TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        final Spacer spacer1 = new Spacer();
        panel2.add(spacer1, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
        final JPanel panel3 = new JPanel();
        panel3.setLayout(new BorderLayout(0, 0));
        panel3.setPreferredSize(new Dimension(120, 0));
        root_panel.add(panel3, BorderLayout.EAST);
        final JPanel panel4 = new JPanel();
        panel4.setLayout(new BorderLayout(0, 0));
        panel4.setPreferredSize(new Dimension(0, 2));
        panel3.add(panel4, BorderLayout.SOUTH);
        final JPanel panel5 = new JPanel();
        panel5.setLayout(new BorderLayout(0, 0));
        panel5.setPreferredSize(new Dimension(0, 2));
        panel3.add(panel5, BorderLayout.NORTH);
        final JToolBar toolBar1 = new JToolBar();
        panel3.add(toolBar1, BorderLayout.CENTER);
        final JLabel label1 = new JLabel();
        label1.setText("前往");
        toolBar1.add(label1);
        page_number_input = new JTextField();
        page_number_input.setHorizontalAlignment(0);
        toolBar1.add(page_number_input);
        final JLabel label2 = new JLabel();
        label2.setText("页");
        toolBar1.add(label2);
    }

    /** @noinspection ALL */
    public JComponent $$$getRootComponent$$$() {
        return root_panel;
    }

    public interface PageChangeListener extends EventListener {
        void handle(Page page);
    }

    public static class Pagination {
        /**
         * 总条数
         */
        private Integer total;
        /**
         * 每页数量
         */
        private Integer pageSize;
        /**
         * 当前页面
         */
        private Integer page;

        public Integer getTotal() {
            return total;
        }

        public void setTotal(Integer total) {
            this.total = total;
        }

        public Integer getPageSize() {
            return pageSize;
        }

        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
        }

        public Integer getPage() {
            return page;
        }

        public void setPage(Integer page) {
            this.page = page;
        }

        @Override
        public String toString() {
            return "Pagination{" + "total=" + total + ", pageSize=" + pageSize + ", page=" + page + '}';
        }
    }

}
